/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.bpm.engine.impl.cmd;

import com.je.bpm.core.model.BpmnModel;
import com.je.bpm.core.model.FlowElement;
import com.je.bpm.core.model.task.KaiteBaseUserTask;
import com.je.bpm.engine.impl.interceptor.Command;
import com.je.bpm.engine.impl.interceptor.CommandContext;
import com.je.bpm.engine.impl.persistence.entity.EarlyWarningLogEntity;
import com.je.bpm.engine.impl.persistence.entity.EarlyWarningLogEntityImpl;
import com.je.bpm.engine.impl.persistence.entity.ExecutionEntity;
import com.je.bpm.engine.impl.persistence.entity.TaskEntity;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

/**
 * 执行预警检查
 */
public class EarlyWarningCheckCmd implements Command<Void>, Serializable {

    private static final String EARLY_WARNING_DESC = "【%s】任务预警，请及时处理！";

    private String processInstanceId;

    public EarlyWarningCheckCmd(String processInstanceId) {
        this.processInstanceId = processInstanceId;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        ExecutionEntity processInstance = commandContext.getProcessEngineConfiguration().getExecutionEntityManager().findById(processInstanceId);
        BpmnModel bpmnModel = commandContext.getProcessEngineConfiguration().getRepositoryService().getBpmnModel(processInstance.getProcessDefinitionId());
        //获取流程实例所有任务
        List<TaskEntity> taskEntities = commandContext.getProcessEngineConfiguration().getTaskEntityManager().findTasksByProcessInstanceId(processInstanceId);
        //获取流程实例所有预警日志
        List<EarlyWarningLogEntity> earlyWarningLogEntities = commandContext.getProcessEngineConfiguration().getEarlyWarningLogEntityManager().findByProcessInstanceId(processInstanceId);
        for (TaskEntity eachTask : taskEntities) {
            FlowElement flowElement = bpmnModel.getFlowElement(eachTask.getTaskDefinitionKey());
            //不是用户任务，则不用处理
            if (!(flowElement instanceof KaiteBaseUserTask)) {
                continue;
            }

            KaiteBaseUserTask kaiteBaseUserTask = (KaiteBaseUserTask) flowElement;
//            TaskEarlyWarningAndPostponementConfigImpl taskEarlyWarningConfig = kaiteBaseUserTask.getTaskEarlyWarningConfig();
//            if (!taskEarlyWarningConfig.isEnabled()) {
//                continue;
//            }

            //获取该任务最近的预警记录，查询已按照NEXT_TIME_倒叙排列
            EarlyWarningLogEntity latestEarlyWarningEntity = null;
            for (EarlyWarningLogEntity eachEntity : earlyWarningLogEntities) {
                if (eachTask.getId().equals(eachEntity.getTaskId())) {
                    latestEarlyWarningEntity = eachEntity;
                    break;
                }
            }

            boolean insert = false;
            Date nowDate = new Date();
//            TaskEarlyWarningAndPostponementConfigImpl.EarlyWarningStrategy earlyWarningStrategy = taskEarlyWarningConfig.getEarlyWarningStrategy();
            Date startDate;
            if (latestEarlyWarningEntity == null) {
                //还没有告警，则根据dueDate计算开始预警时间
                if (nowDate.after(eachTask.getDueDate())) {
                    startDate = nowDate;
                    insert = true;
                } else {
//                    startDate = taskEarlyWarningConfig.getStartDate(eachTask.getDueDate(), taskEarlyWarningConfig.getBeforePeriod(), taskEarlyWarningConfig.getBeforeEarylyWaningPeriodType());
//                    if(nowDate.after(startDate)){
                    insert = true;
//                    }
                }

            } else {
                //已经告警，获取下次告警时间
                startDate = latestEarlyWarningEntity.getNextTime();
                if (nowDate.after(startDate)) {
                    insert = true;
                }
            }

            if (!insert) {
                continue;
            }

            //如果当前时间在nextTime之后或在dueDate设置之前的时间后，则执行预警
            EarlyWarningLogEntity earlyWarningLogEntity = new EarlyWarningLogEntityImpl();
            earlyWarningLogEntity.setAssignee(eachTask.getAssignee());
            earlyWarningLogEntity.setDescription(String.format(EARLY_WARNING_DESC, eachTask.getName()));
            earlyWarningLogEntity.setCreateTime(nowDate);
//            earlyWarningLogEntity.setNextTime(nextDate);
            earlyWarningLogEntity.setProcessDefinitionId(eachTask.getProcessDefinitionId());
            earlyWarningLogEntity.setProcessInstanceId(eachTask.getProcessInstanceId());
            earlyWarningLogEntity.setTaskId(eachTask.getId());
            earlyWarningLogEntity.setTaskName(eachTask.getName());
            earlyWarningLogEntity.setWarnState("CREATED");
            commandContext.getProcessEngineConfiguration().getEarlyWarningLogEntityManager().insert(earlyWarningLogEntity);

            //执行监听，获取方法名，传递当前实体
        }
        return null;
    }

}
